package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"

	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	Cookie = kingpin.Flag("cookie", "b站cookie").Required().Short('c').String()
	Src    = kingpin.Flag("src", "b站直播src").Default("70").Short('s').String()
	Roomid = kingpin.Flag("roomid", "b站直播房间号").Required().Short('r').String()
	doc    = `使用手册:
-c, --网站cookie
-s, --直播线路id
-r, --直播房间号`
)

type Room struct {
	Code    int    `json:"code"`
	Msg     string `json:"msg"`
	Message string `json:"message"`
	Data    struct {
		Status string `json:"status"`
		Change int    `json:"change"`
		Rtmp   struct {
			Addr     string `json:"addr"`
			Code     string `json:"code"`
			NewLink  string `json:"new_link"`
			Provider string `json:"provider"`
		} `json:"rtmp"`
	} `json:"data"`
}

func main() {
	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.UsageTemplate(doc)
	kingpin.Parse()
	f := make(chan bool)
	open_room()
	log.Printf(" [*] 按 CTRL+C 即可退出. 注意:若需要复制文本,选中后按回车即可复制.\n请不要复制到空白文本,否则可能导致开播失败.")
	<-f
}
func open_room() {
	var (
		ret Room
		req *http.Request
	)
	client := &http.Client{}
	csrf := Substr2(*Cookie, strings.Index(*Cookie, "bili_jct=")+9, strings.Index(*Cookie, "bili_jct=")+41)

	query := fmt.Sprintf("room_id=%s&platform=pc&area_v2=27&src=%s&checked=0&csrf_token=%s", *Roomid, *Src, csrf)
	req, _ = http.NewRequest("POST", "https://api.live.bilibili.com/room/v1/Room/startLive", strings.NewReader(query))
	req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Add("Cookie", *Cookie)
	resp, err1 := client.Do(req)
	if err1 != nil {
		log.Fatal(err1)
	}
	json.NewDecoder(resp.Body).Decode(&ret)
	if ret.Code == 0 {
		log.Println("开播成功!")
	} else {
		log.Printf("开播失败,err:%s", ret.Message)
	}
	log.Printf("您的rtmp地址: %s", ret.Data.Rtmp.Addr)
	log.Printf("你的直播码: %s", ret.Data.Rtmp.Code)
}
func Substr2(str string, start int, end int) string {
	rs := []rune(str)
	length := len(rs)
	if start < 0 || start > length {
		panic("start is wrong")
	}

	if end < 0 || end > length {
		panic("end is wrong")
	}

	return string(rs[start:end])
}
